package com.ruoyi.web.util.pdf;

import com.itextpdf.text.pdf.PdfSignatureAppearance;
import com.itextpdf.text.pdf.security.ExternalDigest;
import com.itextpdf.text.pdf.security.ExternalSignature;
import com.itextpdf.text.pdf.security.MakeSignature;
import com.ruoyi.web.bean.ESSPdfPage;

import com.ruoyi.web.bean.PDFPage;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.List;

import static com.itextpdf.local.ess.FileUtils.File2byte;
import static com.ruoyi.common.utils.Base64Utils.ESSGetBase64Encode;

/**
 * @author ：chen
 * @date ：Created in 2019/9/27 15:13
 */
public class PdfUtils {

    public static void addSealByRSA(PdfSignatureAppearance appearance, ExternalDigest digest, Certificate[] chain, ExternalSignature es ) throws Exception {
        MakeSignature.signDetached(appearance, digest, es, chain, null, null, null, 0,
                MakeSignature.CryptoStandard.CMS);
    }
    public static void addSeal_UK(PdfSignatureAppearance appearance, ExternalDigest digest,Certificate[] chain, String UKID) throws Exception {
        EssMakeSignature.signDetached(appearance, digest, null, chain, null, null, null,
                0, MakeSignature.CryptoStandard.CMS,UKID);
    }

    /**
     * 将pdf文件切割成JPG文件用于网页上显示
     * @param pdfFile 文件
     * @return ESSPdfPage
     */
    public static List<ESSPdfPage> splitPDF(File pdfFile) {
        String documentCode = pdfFile.getParentFile().getName();
        List<ESSPdfPage> result = new ArrayList<>();
        PDDocument document = null;
        try {
            //启动一个线程处理图片，页面上懒加载。
            Runnable runnable1 = new PdfUtils().dealMsg1(pdfFile);
            new Thread(runnable1).start();
            document = PDDocument.load(pdfFile);
            PDFRenderer pdfRenderer = new PDFRenderer(document);
            int pageNum=0;
            for (PDPage page : document.getPages()) {
                pageNum++;
                ESSPdfPage pdf = new ESSPdfPage();
                pdf.setPageSize(getPageInfo(page));
                pdf.setPicPath(documentCode+"\\\\"+pdfFile.getName()+pageNum+".png");
                result.add(pdf);
            }
            BufferedImage bim = pdfRenderer.renderImageWithDPI(0, 96, ImageType.RGB);
            ImageIO.write(bim, "png", new File(pdfFile.getAbsolutePath()+1+".png"));

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                document.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }




    //创建一个Runnable，重写run方法
    public Runnable dealMsg(BufferedImage bim,String absolutePath,int pageNum){
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                //保存分页为图片
                try {
                    if (!new File(absolutePath+pageNum+".png").exists()){
                        ImageIO.write(bim, "png", new File( absolutePath+pageNum+".png"));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };
        return runnable;
    }
    //创建一个Runnable，重写run方法
    public Runnable dealMsg1(File pdfFile){
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                String path = pdfFile.getAbsolutePath();
                String documentCode = path.split("\\\\")[2];
                PDDocument document = null;
                try {
                    document = PDDocument.load(pdfFile);
                    PDFRenderer pdfRenderer = new PDFRenderer(document);
                    int pageNum=0;
                    for (PDPage page : document.getPages()) {
                        BufferedImage bim = pdfRenderer.renderImageWithDPI(pageNum, 96, ImageType.RGB);
                        pageNum++;
                        Runnable runnable = new PdfUtils().dealMsg(bim,pdfFile.getAbsolutePath(),pageNum);
                        new Thread(runnable).start();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    try {
                        document.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        return runnable;
    }

    /**
     * 获得传入Pdf页面对象获得页面大小信息
     * @param page
     * @return
     */
    public static String getPageInfo(PDPage page) {
        int width = (int) page.getMediaBox().getWidth();
        int height = (int) page.getMediaBox().getHeight();
        return width + "_" + height;
    }
    /**
     * 将印章数据中的大小mm转换为pdf内坐标大小 42 119 44 124
     */
    public static int convertCoordinate(int mm) {
        return (595*mm)/210;
    }

    public static float convertCoordinate(float mm) {
        return (595.32f*mm)/210;
    }

    /**
     * 将pdf内坐标mm转换为mm 42 119 44 124
     * 210mm×297mm
     */
    public static float convertLength(float cd) {
//        float cd =  841.92f;
//        float a = (210*cd)/595.32f;
        return (210*cd)/595.32f;
    }

    /**
     * 将pdf文件切割成JPG文件用于网页上显示
     * @param pdfFile PDF文件
     * @param pageNum 文件页数
     * @param dpi 图像的dpi（清晰度） 建议96
     * @return
     */
    public static PDFPage getPDFPageImg(byte[] pdfFile, int pageNum, int dpi) {
        PDDocument document;
        PDFPage pdfPage = new PDFPage();
        int tolNum;
        try {
            document = PDDocument.load(pdfFile);
            //加载PDF文件
            PDFRenderer pdfRenderer = new PDFRenderer(document);
            //获取文件总页数
            tolNum = document.getNumberOfPages();
            if (pageNum>tolNum){
                return null;
            }
            //获取PDF单页的图像数据
            BufferedImage bim = pdfRenderer.renderImageWithDPI(pageNum-1, dpi, ImageType.RGB);
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            ImageIO.write(bim, "png", stream);
            stream.flush();
            byte[]  imageInByte = stream.toByteArray();

            //获取PDF页面的宽高数据
            float width =document.getPage(pageNum-1).getMediaBox().getWidth();

            float height = document.getPage(pageNum-1).getMediaBox().getHeight();

            pdfPage.setWidth(convertLength(width));
            pdfPage.setHeight(convertLength(height));

            pdfPage.setPageNum(pageNum);
            pdfPage.setTolNum(tolNum);

            pdfPage.setImageBase64(ESSGetBase64Encode(imageInByte));
            return pdfPage;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        System.out.println(getPDFPageImg(File2byte("D:\\Desktop\\20220519100541(删除).pdf"),2,96));
    }
}
